home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / g__~1 / gplibs15.zoo / iostream.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-01  |  15.4 KB  |  724 lines

  1. //    This is part of the iostream library, providing input/output for C++.
  2. //    Copyright (C) 1991 Per Bothner.
  3. //
  4. //    This library is free software; you can redistribute it and/or
  5. //    modify it under the terms of the GNU Library General Public
  6. //    License as published by the Free Software Foundation; either
  7. //    version 2 of the License, or (at your option) any later version.
  8. //
  9. //    This library is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. //    Library General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU Library General Public
  15. //    License along with this library; if not, write to the Free
  16. //    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #ifdef __GNUG__
  19. #pragma implementation
  20. #endif
  21. #define _STREAM_COMPAT
  22. #include <ioprivat.h>
  23. #include <iostream.h>
  24. #include <stdio.h>  /* Needed for sprintf */
  25. #include <ctype.h>
  26. #include <floatio.h>
  27.  
  28. #define    BUF        (MAXEXP+MAXFRACT+1)    /* + decimal point */
  29.  
  30. //#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
  31.  
  32. extern backupbuf not_open_filebuf;
  33.  
  34. istream::istream(streambuf *sb, ostream* tied) : ios(sb, tied)
  35. {
  36.     _flags |= ios::dont_close;
  37.     _gcount = 0;
  38. }
  39.  
  40. int skip_ws(streambuf* sb)
  41. {
  42.     int ch;
  43.     for (;;) {
  44.     ch = sb->sbumpc();
  45.     if (ch == EOF || !isspace(ch))
  46.         return ch;
  47.     }
  48. }
  49.  
  50. istream& istream::get(char& c)
  51. {
  52.     if (ipfx1()) {
  53.     int ch = _strbuf->sbumpc();
  54.     if (ch == EOF) set(ios::eofbit|ios::failbit);
  55.     else c = (char)ch;
  56.     }
  57.     return *this;
  58. }
  59.  
  60. istream& istream::ignore(int n=1, int delim = EOF)
  61. {
  62.     if (ipfx1()) {
  63.     register streambuf* sb = _strbuf;
  64.     if (delim == EOF) {
  65.         _gcount = sb->ignore(n);
  66.         return *this;
  67.     }
  68.     _gcount = 0;
  69.     for (;;) {
  70. #if 0
  71.         if (n != MAXINT) // FIXME
  72. #endif
  73.         if (--n < 0)
  74.         break;
  75.         int ch = sb->sbumpc();
  76.         if (ch == EOF) {
  77.         set(ios::eofbit|ios::failbit);
  78.         break;
  79.         }
  80.         _gcount++;
  81.         if (ch == delim)
  82.         break;
  83.     }
  84.     }
  85.     return *this;
  86. }
  87.  
  88. istream& istream::read(char *s, size_t n)
  89. {
  90.     if (ipfx1()) {
  91.     _gcount = _strbuf->sgetn(s, n);
  92.     if (_gcount != n)
  93.         set(ios::failbit);
  94.     }
  95.     return *this;
  96. }
  97.  
  98. istream& istream::seekg(streampos pos)
  99. {
  100.     pos = _strbuf->seekpos(pos, ios::in);
  101.     if (pos == streampos(EOF))
  102.     set(ios::badbit);
  103.     return *this;
  104. }
  105.  
  106. istream& istream::seekg(streamoff off, _seek_dir dir)
  107. {
  108.     streampos pos = _strbuf->seekoff(off, dir, ios::in);
  109.     if (pos == streampos(EOF))
  110.     set(ios::badbit);
  111.     return *this;
  112. }
  113.  
  114. streampos istream::tellg()
  115. {
  116.     streampos pos = _strbuf->seekoff(0, ios::cur, ios::in);
  117.     if (pos == streampos(EOF))
  118.     set(ios::badbit);
  119.     return pos;
  120. }
  121.  
  122. istream& istream::scan(const char *format ...)
  123. {
  124.     if (ipfx0()) {
  125.     va_list ap;
  126.     va_start(ap, format);
  127.     _strbuf->vscan(format, ap, &_state);
  128.     va_end(ap);
  129.     }
  130.     return *this;
  131. }
  132.  
  133. istream& istream::vscan(const char *format, _G_va_list args)
  134. {
  135.     if (ipfx0())
  136.     _strbuf->vscan(format, args, &_state);
  137.     return *this;
  138. }
  139.  
  140. istream& operator>>(istream& is, char& c)
  141. {
  142.     if (is.ipfx0()) {
  143.     int ch = is._strbuf->sbumpc();
  144.     if (ch == EOF)
  145.         is.set(ios::eofbit|ios::failbit);
  146.     else
  147.         c = (char)ch;
  148.     }
  149.     return is;
  150. }
  151.  
  152. istream& operator>>(istream& is, char* ptr)
  153. {
  154.     if (is.ipfx0()) {
  155.     register streambuf* sb = is._strbuf;
  156.     int ch = sb->sbumpc();
  157.     if (ch == EOF)
  158.         is.set(ios::eofbit|ios::failbit);
  159.     else {
  160.         int w = is.width(0);
  161.         *ptr++ = ch;
  162.         for (;;) {
  163.         ch = sb->sbumpc();
  164.         if (ch == EOF) {
  165.             is.set(ios::eofbit|ios::failbit);
  166.             break;
  167.         }
  168.         else if (isspace(ch)) {
  169.             sb->sputbackc(ch);
  170.             break;
  171.         }
  172.         else if (w == 1) {
  173.             is.set(ios::failbit);
  174.             sb->sputbackc(ch);
  175.             break;
  176.         }
  177.         else *ptr++ = ch;
  178.         w--;
  179.         }
  180.     }
  181.     }
  182.     *ptr = '\0';
  183.     return is;
  184. }
  185.  
  186. static int read_int(istream& stream, unsigned long& val, int& neg)
  187. {
  188.     if (!stream.ipfx0())
  189.     return 0;
  190.     register streambuf* sb = stream.rdbuf();
  191.     int base = 10;
  192.     int ndigits = 0;
  193.     register int ch = skip_ws(sb);
  194.     if (ch == EOF)
  195.     goto eof_fail;
  196.     neg = 0;
  197.     if (ch == '+') {
  198.     ch = skip_ws(sb);
  199.     }
  200.     else if (ch == '-') {
  201.     neg = 1;
  202.     ch = skip_ws(sb);
  203.     }
  204.     if (ch == EOF) goto eof_fail;
  205.     if (!(stream.flags() & (ios::hex|ios::dec|ios::oct))) {
  206.     if (ch == '0') {
  207.         ch = sb->sbumpc();
  208.         if (ch == EOF) {
  209.         val = 0;
  210.         return 1;
  211.         }
  212.         if (ch == 'x' || ch == 'X') {
  213.         base = 16;
  214.         ch = sb->sbumpc();
  215.         if (ch == EOF) goto eof_fail;
  216.         }
  217.         else {
  218.         sb->sputbackc(ch);
  219.         base = 8;
  220.         ch = '0';
  221.         }
  222.     }
  223.     }
  224.     else if (stream.flags() & ios::hex)
  225.     base = 16;
  226.     else if (stream.flags() & ios::oct)
  227.     base = 8;
  228.     val = 0;
  229.     for (;;) {
  230.     if (ch == EOF)
  231.         break;
  232.     int digit;
  233.     if (ch >= '0' && ch <= '9')
  234.         digit = ch - '0';
  235.     else if (ch >= 'A' && ch <= 'F')
  236.         digit = ch - 'A' + 10;
  237.     else if (ch >= 'a' && ch <= 'f')
  238.         digit = ch - 'a' + 10;
  239.     else
  240.         digit = 999;
  241.     if (digit >= base) {
  242.         sb->sputbackc(ch);
  243.         if (ndigits == 0)
  244.         goto fail;
  245.         else
  246.         return 1;
  247.     }
  248.     ndigits++;
  249.     val = base * val + digit;
  250.     ch = sb->sbumpc();
  251.     }
  252.     return 1;
  253.   fail:
  254.     stream.set(ios::failbit);
  255.     return 0;
  256.   eof_fail:
  257.     stream.set(ios::failbit|ios::eofbit);
  258.     return 0;
  259. }
  260.  
  261. #define READ_INT(TYPE) \
  262. istream& operator>>(istream& is, TYPE& i)\
  263. {\
  264.     unsigned long val; int neg;\
  265.     if (read_int(is, val, neg)) {\
  266.     if (neg) val = -val;\
  267.     i = (TYPE)val;\
  268.     }\
  269.     return is;\
  270. }
  271.  
  272. READ_INT(short)
  273. READ_INT(unsigned short)
  274. READ_INT(int)
  275. READ_INT(unsigned int)
  276. READ_INT(long)
  277. READ_INT(unsigned long)
  278.  
  279. istream& operator>>(istream& is, double& x)
  280. {
  281.     if (is.ipfx0()) {
  282.     is.scan("%lg", &x);
  283.     }
  284.     return is;
  285. }
  286. istream& operator>>(istream& is, float& x)
  287. {
  288.     if (is.ipfx0()) {
  289.     is.scan("%g", &x);
  290.     }
  291.     return is;
  292. }
  293.  
  294. istream& operator>>(istream& is, register streambuf* sbuf)
  295. {
  296.     if (is.ipfx0()) {
  297.     register streambuf* inbuf = is.rdbuf();
  298.     // FIXME: Should optimize!
  299.     for (;;) {
  300.         register int ch = inbuf->sbumpc();
  301.         if (ch == EOF) {
  302.         is.set(ios::eofbit);
  303.         break;
  304.         }
  305.         if (sbuf->sputc(ch) == EOF) {
  306.         is.set(ios::failbit);
  307.         break;
  308.         }
  309.     }
  310.     }
  311.     return is;
  312. }
  313.  
  314. ostream& operator<<(ostream& os, char c)
  315. {
  316.     if (os.opfx()) {
  317.     int w = os.width(0);
  318.     char fill_char = os.fill();
  319.     register int padding = w > 0 ? w - 1 : 0;
  320.     register streambuf *sb = os._strbuf;
  321.     if (!(os.flags() & ios::left)) // Default adjustment.
  322.         while (--padding >= 0) sb->sputc(fill_char);
  323.     sb->sputc(c);
  324.     if (os.flags() & ios::left) // Left adjustment.
  325.         while (--padding >= 0) sb->sputc(fill_char);
  326.     os.osfx();
  327.     }
  328.     return os;
  329. }
  330.  
  331. void write_int(ostream& stream, unsigned long val, int neg)
  332. {
  333.     char buf[10 + sizeof(unsigned long) * 3];
  334.     char *show_base = "";
  335.     int show_base_len = 0;
  336.     if ((stream.flags() & (ios::oct|ios::hex)) == 0) // Decimal
  337.     sprintf(buf, "%lu", val);
  338.     else if (stream.flags() & ios::oct) { // Oct
  339.     sprintf(buf, "%lo", val);
  340.     if (stream.flags() & ios::showbase)
  341.         show_base = "0", show_base_len = 1;
  342.     }
  343.     else if (stream.flags() & ios::uppercase) {// Hex
  344.     sprintf(buf, "%lX", val);
  345.     if (stream.flags() & ios::showbase)
  346.         show_base = "0X", show_base_len = 2;
  347.     }
  348.     else { // Hex
  349.     sprintf(buf, "%lx", val);
  350.     if (stream.flags() & ios::showbase)
  351.         show_base = "0x", show_base_len = 2;
  352.     }
  353.     int buf_len = strlen(buf);
  354.     int w = stream.width(0);
  355.     int show_pos = 0;
  356.  
  357.     // Calculate padding.
  358.     int len = buf_len;
  359.     if (neg) len++;
  360.     else if (val != 0 && (stream.flags() & ios::showpos)) len++, show_pos=1;
  361.     len += show_base_len;
  362.     int padding = len > w ? 0 : w - len;
  363.  
  364.     // Do actual output.
  365.     register streambuf* sbuf = stream.rdbuf();
  366.     ios::fmtflags pad_kind =
  367.     stream.flags() & (ios::left|ios::right|ios::internal);
  368.     char fill_char = stream.fill();
  369.     if (padding > 0
  370.     && pad_kind != (ios::fmtflags)ios::left
  371.     && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
  372.     sbuf->padn(fill_char, padding);
  373.     if (neg) sbuf->sputc('-');
  374.     else if (show_pos) sbuf->sputc('+');
  375.     if (show_base_len)
  376.     sbuf->sputn(show_base, show_base_len);
  377.     if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
  378.     sbuf->padn(fill_char, padding);
  379.     sbuf->sputn(buf, buf_len);
  380.     if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
  381.     sbuf->padn(fill_char, padding);
  382.     stream.osfx();
  383. }
  384.  
  385. ostream& operator<<(ostream& os, int n)
  386. {
  387.     if (os.opfx()) {
  388.     int neg = 0;
  389.     if (n < 0 && (os.flags() & (ios::oct|ios::hex)) == 0)
  390.         n = -n, neg = 1;
  391.     write_int(os, n, neg);
  392.     }
  393.     return os;
  394. }
  395.  
  396. ostream& operator<<(ostream& os, long n)
  397. {
  398.     if (os.opfx()) {
  399.     int neg = 0;
  400.     if (n < 0 && (os.flags() & (ios::oct|ios::hex)) == 0)
  401.         n = -n, neg = 1;
  402.     write_int(os, n, neg);
  403.     }
  404.     return os;
  405. }
  406.  
  407. ostream& operator<<(ostream& os, unsigned int n)
  408. {
  409.     if (os.opfx())
  410.     write_int(os, n, 0);
  411.     return os;
  412. }
  413.  
  414. ostream& operator<<(ostream& os, unsigned long n)
  415. {
  416.     if (os.opfx())
  417.     write_int(os, n, 0);
  418.     return os;
  419. }
  420.  
  421. ostream& operator<<(ostream& os, float n)
  422. {
  423.     return os << (double)n;
  424. }
  425.  
  426. ostream& operator<<(ostream& os, double n)
  427. {
  428.     if (os.opfx()) {
  429.     // Uses __cvt_double (renamed from static cvt), in Chris Torek's
  430.     // stdio implementation.  The setup code uses the same logic
  431.     // as in __vsbprintf.C (also based on Torek's code).
  432.     int format_char;
  433. #if 0
  434.     if (os.flags() ios::showpos) sign = '+';
  435. #endif
  436.     if (os.flags() & ios::fixed)
  437.         format_char = 'f';
  438.     else if (os.flags() & ios::scientific)
  439.         format_char = os.flags() & ios::uppercase ? 'E' : 'e';
  440.     else
  441.         format_char = os.flags() & ios::uppercase ? 'G' : 'g';
  442.  
  443.     int fpprec = 0; // 'Extra' (suppressed) floating precision.
  444.     int prec = os.precision();
  445.     if (prec < 0) prec = 6; // default.
  446.     else if (prec > MAXFRACT) {
  447.         if (os.flags() & (ios::fixed|ios::scientific) & ios::showpos)
  448.         fpprec = prec - MAXFRACT;
  449.         prec = MAXFRACT;
  450.     }
  451.  
  452.     // Do actual conversion.
  453. #ifdef USE_DTOA
  454.     if (__outfloat(n, os.rdbuf(), format_char, os.width(0),
  455.                os.precision(), os.flags(), 0, os.fill()) < 0)
  456.         os.set(ios::badbit|ios::failbit); // ??
  457. #else
  458.     int negative;
  459.     char buf[BUF];
  460.     int sign = '\0';
  461.     char *cp = buf;
  462.     *cp = 0;
  463.     int size = __cvt_double(n, os.precision(),
  464.                 os.flags() & ios::showpoint ? 0x80 : 0,
  465.                 &negative,
  466.                 format_char, cp, buf + sizeof(buf));
  467.     if (negative) sign = '-';
  468.     if (*cp == 0)
  469.         cp++;
  470.  
  471.     // Calculate padding.
  472.     int fieldsize = size + fpprec;
  473.     if (sign) fieldsize++;
  474.     int padding = 0;
  475.     int w = os.width(0);
  476.     if (fieldsize < w)
  477.         padding = w - fieldsize;
  478.  
  479.     // Do actual output.
  480.     register streambuf* sbuf = os.rdbuf();
  481.     register i;
  482.     char fill_char = os.fill();
  483.     ios::fmtflags pad_kind =
  484.         os.flags() & (ios::left|ios::right|ios::internal);
  485.     if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
  486.         && pad_kind != (ios::fmtflags)ios::internal)
  487.         for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  488.     if (sign)
  489.         sbuf->sputc(sign);
  490.     if (pad_kind == (ios::fmtflags)ios::internal)
  491.         for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  492.     
  493.     // Emit the actual concented field, followed by extra zeros.
  494.     sbuf->sputn(cp, size);
  495.     for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
  496.  
  497.     if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
  498.         for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  499. #endif
  500.     os.osfx();
  501.     }
  502.     return os;
  503. }
  504.  
  505. ostream& operator<<(ostream& stream, const char *s)
  506. {
  507.     if (stream.opfx()) {
  508.     size_t len = strlen(s);
  509.     int w = stream.width(0);
  510.     char fill_char = stream.fill();
  511.     register streambuf *sbuf = stream.rdbuf();
  512.     register int padding = w > len ? w - len : 0;
  513.     if (!(stream.flags() & ios::left)) // Default adjustment.
  514.         while (--padding >= 0) sbuf->sputc(fill_char);
  515.     sbuf->sputn(s, len);
  516.     if (stream.flags() & ios::left) // Left adjustment.
  517.         while (--padding >= 0) sbuf->sputc(fill_char);
  518.     stream.osfx();
  519.     }
  520.     return stream;
  521. }
  522.  
  523. ostream& operator<<(ostream& os, void *p)
  524. {
  525.     if (os.opfx()) {
  526.     os.form("%p", p);
  527.     os.osfx();
  528.     }
  529.     return os;
  530. }
  531.  
  532. ostream& operator<<(ostream& os, register streambuf* sbuf)
  533. {
  534.     if (os.opfx()) {
  535.     register streambuf* outbuf = os.rdbuf();
  536.     // FIXME: Should optimize!
  537.     for (;;) {
  538.         register int ch = sbuf->sbumpc();
  539.         if (ch == EOF) break;
  540.         if (outbuf->sputc(ch) == EOF) {
  541.         os.set(ios::badbit);
  542.         break;
  543.         }
  544.     }
  545.     os.osfx();
  546.     }
  547.     return os;
  548. }
  549.  
  550. ostream::ostream(streambuf* sb, ostream* tied) : ios(sb, tied)
  551. {
  552.     _flags |= ios::dont_close;
  553. }
  554.  
  555. ostream& ostream::seekp(streampos pos)
  556. {
  557.     pos = _strbuf->seekpos(pos, ios::out);
  558.     if (pos == streampos(EOF))
  559.     set(ios::badbit);
  560.     return *this;
  561. }
  562.  
  563. ostream& ostream::seekp(streamoff off, _seek_dir dir)
  564. {
  565.     streampos pos = _strbuf->seekoff(off, dir, ios::out);
  566.     if (pos == streampos(EOF))
  567.     set(ios::badbit);
  568.     return *this;
  569. }
  570.  
  571. streampos ostream::tellp()
  572. {
  573.     streampos pos = _strbuf->seekoff(0, ios::cur, ios::out);
  574.     if (pos == streampos(EOF))
  575.     set(ios::badbit);
  576.     return pos;
  577. }
  578.  
  579. ostream& ostream::form(const char *format ...)
  580. {
  581.     if (opfx()) {
  582.     va_list ap;
  583.     va_start(ap, format);
  584.     _strbuf->vform(format, ap);
  585.     va_end(ap);
  586.     }
  587.     return *this;
  588. }
  589.  
  590. ostream& ostream::vform(const char *format, _G_va_list args)
  591. {
  592.     if (opfx())
  593.     _strbuf->vform(format, args);
  594.     return *this;
  595. }
  596.  
  597. ostream& ostream::flush()
  598. {
  599.     if (_strbuf->sync())
  600.     set(ios::badbit);
  601.     return *this;
  602. }
  603.  
  604. ostream& flush(ostream& outs)
  605. {
  606.     outs.rdbuf()->overflow(EOF);
  607.     return outs;
  608. }
  609.  
  610. istream& ws(istream& ins)
  611. {
  612.     if (ins.ipfx1()) {
  613.     int ch = skip_ws(ins._strbuf);
  614.     if (ch == EOF)
  615.         ins.set(ios::eofbit);
  616.     else
  617.         ins._strbuf->sputbackc(ch);
  618.     }
  619.     return ins;
  620. }
  621.  
  622. // Skip white-space.  Return 0 on failure (EOF), or 1 on success.
  623. // Differs from ws() manipulator in that failbit is set on EOF.
  624. // Called by ipfx() and ipfx0() if needed.
  625.  
  626. int istream::_skip_ws()
  627. {
  628.     int ch = skip_ws(_strbuf);
  629.     if (ch == EOF) {
  630.     set(ios::eofbit|ios::failbit);
  631.     return 0;
  632.     }
  633.     else {
  634.     _strbuf->sputbackc(ch);
  635.     return 1;
  636.     }
  637. }
  638.  
  639. ostream& ends(ostream& outs)
  640. {
  641.     outs.put(0);
  642.     return outs;
  643. }
  644.  
  645. ostream& endl(ostream& outs)
  646. {
  647.     return flush(outs.put('\n'));
  648. }
  649.  
  650. ostream& ostream::write(const char *s, size_t n)
  651. {
  652.     if (opfx()) {
  653.     if (_strbuf->sputn(s, n) != n)
  654.         set(ios::failbit);
  655.     }
  656.     return *this;
  657. }
  658.  
  659. void ostream::do_osfx()
  660. {
  661.     if (flags() & ios::unitbuf)
  662.     flush();
  663.     if (flags() & ios::stdio) {
  664.     fflush(stdout);
  665.     fflush(stderr);
  666.     }
  667. }
  668.  
  669. const unsigned long ios::basefield = ios::hex|ios::oct|ios::dec;
  670. const unsigned long ios::floatfield = ios::scientific|ios::fixed;
  671. const unsigned long ios::adjustfield =
  672.     ios::left|ios::right|ios::internal;
  673.  
  674. iostream::iostream(streambuf* sb, ostream* tied) : ios(sb, tied)
  675. {
  676.     _flags |= ios::dont_close;
  677.     _gcount = 0;
  678. }
  679.  
  680. ostream& iostream::form(const char *format ...) // Copy of ostream::form.
  681. {
  682.     va_list ap;
  683.     va_start(ap, format);
  684.     _strbuf->vform(format, ap);
  685.     va_end(ap);
  686.     return *(ostream*)this;
  687. }
  688. istream& iostream::scan(const char *format ...) // Copy of istream::scan
  689. {
  690.     if (ipfx0()) {
  691.     va_list ap;
  692.     va_start(ap, format);
  693.     _strbuf->vscan(format, ap, &_state);
  694.     va_end(ap);
  695.     }
  696.     return *this;
  697. }
  698.  
  699. // NOTE: extension for compatibility with old libg++.
  700. // Not really compatible with fistream::close().
  701. #ifdef _STREAM_COMPAT
  702. void ios::close()
  703. {
  704.     if (!(_flags & (unsigned int)ios::dont_close))
  705.     delete _strbuf;
  706.     else if (_strbuf->_flags & _S_IS_FILEBUF)
  707.     ((struct filebuf*)_strbuf)->close();
  708.     else if (_strbuf != ¬_open_filebuf)
  709.     _strbuf->sync();
  710.     _flags |= ios::dont_close;
  711.     _strbuf = ¬_open_filebuf;
  712. }
  713.  
  714. int istream::skip(int i)
  715. {
  716.     int old = (_flags & ios::skipws) != 0;
  717.     if (i)
  718.     _flags |= ios::skipws;
  719.     else
  720.     _flags &= ~ios::skipws;
  721.     return old;
  722. }
  723. #endif
  724.